# coding=utf-8
from string import Template
from typing import Dict, List
from generator.libsomeip.some_ip_type import Message, SomeIP

from utils.util import writeFile

SomeIP_json_config = Template(
    """{
    "unicast" : "198.18.34.15",
    "logging" : {
        "level" : "trace",
        "console" : "true",
        "file" : {
            "enable" : "false"
        },
        "dlt" : "false"
    },
    "applications" : [
        {
            "name":"SomeIPFromSlaveService",
            "id":"0x5579"
        }
    ],
    "services" : [${offer_services}
    ],
    "clients" : [${clients}
    ],
    "routing" : "SomeIPFromSlaveService",
    "service-discovery" : {
        "enable" : "true",
        "mode" : "unicast",
        "unicast" : [
            "198.18.34.2","198.18.34.15"
        ],
        "multicast" : "224.244.224.245",
        "port" : "30490",
        "protocol" : "udp",
        "initial_delay_min" : "10",
        "initial_delay_max" : "100",
        "cyclic_offer_delay":"10000",
        "request_response_delay":"1500"
    }
}
""")

offer_service_template = Template(
"""
        {
            "service" : "${serviceId}",
            "instance" : "0x1",
            "reliable" : {
                "port" : "${servicePort}",
                "enable-magic-cookies" : "true"
            },
            "events" : [${events}
            ],
            "eventgroups" : [${event_goups}
            ]
        }"""
)

client_templete=Template(
"""
        {
			"service": "${serviceId}",
			"instance": "0x01",
			"reliable": [ "${port}" ]
		}"""
)

event_template=Template(
"""
                {
                    "event" : "${eventId}",
                    "is_field" : "true",
                    "is_reliable" : "true",
                    "update-cycle" : 2000
                }"""
)

event_group_template=Template(
"""
                {
                    "eventgroup" : "${eventGroup}",
                    "events" : [
                        ${eventIds}
                    ]
                }"""
)

        

def gen_SomeIPConfigJson(someip: SomeIP):
    offerServices=[]
    clients=[]
    offServiceMap:Dict[str,List[Message]]={}
    clientServiceMap:Dict[str,List[Message]]={}
    port = 40000
    for msg in someip.msg:
        if msg.isOfferMessage():
            msgs=offServiceMap.get(msg.serviceId,[])
            msgs.append(msg)
            offServiceMap[msg.serviceId]=msgs
        else:
            msgs=clientServiceMap.get(msg.serviceId,[])
            msgs.append(msg)
            clientServiceMap[msg.serviceId]=msgs

    for serviceId,msgs in offServiceMap.items():
        events_template=[]
        groups_template=[]
        eventGroups:Dict[str,List[str]]={}
        for msg in msgs:
            if msg.isOfferMessage():
                events_template.append(event_template.substitute(
                    eventId=msg.methodId
                ))
                if msg.eventGroupId.strip() != "" and msg.isNotifyMessage():
                    eventIds=eventGroups.get(msg.eventGroupId,[])
                    eventIds.append(msg.methodId)
                    eventGroups[msg.eventGroupId]=eventIds
        for gId, events in eventGroups.items():
            groups_template.append(event_group_template.substitute(
                    eventGroup=gId,
                    eventIds=",".join(["{0}{1}{0}".format("\"",eventId) for eventId in events])
                ))
        offerServices.append(offer_service_template.substitute(
            serviceId=serviceId,
            servicePort=str(port),
            events=",".join(events_template),
            event_goups=",".join(groups_template)
        ))
        port += 1

    for serviceId,msgs in clientServiceMap.items():
        clients.append(client_templete.substitute(
            serviceId=someip.serviceId,
            port=str(port),
        ))
        port += 1
    writeFile("./data/transfer/libsomeip/", "vsomeip_cfg.json", lambda file: file.write(SomeIP_json_config.substitute(
        offer_services=",".join(offerServices),
        clients = ",".join(clients)
    )))
